from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QTableWidget, QTableWidgetItem, QHeaderView, QMessageBox,
    QDialog, QAbstractItemView, QComboBox
)
from PyQt5.QtCore import Qt
import json

class ParamEditorDialog(QDialog):
    def __init__(self, parent=None, initial_params=None):
        super().__init__(parent)
        self.setWindowTitle("Edit Params")
        self.initial_params = initial_params or []
        self.initUI()
        

    def initUI(self):
        self.setGeometry(100, 300, 800, 400)
        self.layout = QVBoxLayout()

        # 表格显示 Params
        self.table = QTableWidget()
        self.table.setRowCount(len(self.initial_params))
        self.table.setColumnCount(5)
        self.table.setHorizontalHeaderLabels(["Name", "Type", "Value", "Description", "Unit"])
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.table.setEditTriggers(QAbstractItemView.AllEditTriggers)

        # 初始化表格内容
        for row, param in enumerate(self.initial_params):
            self.table.setItem(row, 0, QTableWidgetItem(param.get("name", "")))
            self.table.setCellWidget(row, 1, QComboBox())  # Type 选项改为下拉框
            self.table.cellWidget(row, 1).addItems(["double", "int", "bool", "string"])
            self.table.cellWidget(row, 1).setCurrentText(param.get("type", ""))
            self.table.setItem(row, 2, QTableWidgetItem(param.get("value", "")))
            self.table.setItem(row, 3, QTableWidgetItem(param.get("Description", "")))
            self.table.setItem(row, 4, QTableWidgetItem(param.get("unit", "")))

        self.layout.addWidget(self.table)

        # 添加按钮
        button_layout = QHBoxLayout()
        self.add_button = QPushButton("Add Param")
        self.add_button.clicked.connect(self.add_param)
        self.delete_button = QPushButton("Delete Param")
        self.delete_button.clicked.connect(self.delete_param)
        self.save_button = QPushButton("Save")
        self.save_button.clicked.connect(self.accept)
        button_layout.addWidget(self.add_button)
        button_layout.addWidget(self.delete_button)
        button_layout.addWidget(self.save_button)
        self.layout.addLayout(button_layout)

        self.setLayout(self.layout)

    def add_param(self):
        row_count = self.table.rowCount()
        self.table.insertRow(row_count)
        self.table.setItem(row_count, 0, QTableWidgetItem(""))  # Name
        self.table.setCellWidget(row_count, 1, QComboBox())  # Type
        self.table.cellWidget(row_count, 1).addItems(["double", "int", "bool", "string"])
        self.table.setItem(row_count, 2, QTableWidgetItem(""))  # Value
        self.table.setItem(row_count, 3, QTableWidgetItem(""))  # Description
        self.table.setItem(row_count, 4, QTableWidgetItem(""))  # Unit

    def delete_param(self):
        selected_rows = self.table.selectionModel().selectedRows()
        if selected_rows:
            for row in sorted(selected_rows, reverse=True):
                self.table.removeRow(row.row())
        else:
            QMessageBox.warning(self, "Warning", "No row selected to delete.")

    def get_params(self):
        params = []
        for row in range(self.table.rowCount()):
            param = {
                "name": self.table.item(row, 0).text() if self.table.item(row, 0) else "",
                "type": self.table.cellWidget(row, 1).currentText(),
                "value": self.table.item(row, 2).text() if self.table.item(row, 2) else "",
                "Description": self.table.item(row, 3).text() if self.table.item(row, 3) else "",
                "unit": self.table.item(row, 4).text() if self.table.item(row, 4) else ""
            }
            params.append(param)
        return params


class SubCompEditorDialog(QDialog):
    def __init__(self, parent=None, initial_sub_comps=None):
        super().__init__(parent)
        self.setWindowTitle("Edit Sub Components")
        self.initial_sub_comps = initial_sub_comps or []
        self.initUI()
    def initUI(self):
        self.setGeometry(100, 300, 800, 400)
        self.layout = QVBoxLayout()

        # 表格显示 Sub Components
        self.table = QTableWidget()
        self.table.setRowCount(len(self.initial_sub_comps))
        self.table.setColumnCount(5)
        self.table.setHorizontalHeaderLabels(["Class Name", "Name", "Nodes", "Params", "Sub Comps"])
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.table.setEditTriggers(QAbstractItemView.AllEditTriggers)

        # 初始化表格内容
        for row, sub_comp in enumerate(self.initial_sub_comps):
            self.table.setItem(row, 0, QTableWidgetItem(sub_comp.get("name", "")))
            self.table.setItem(row, 1, QTableWidgetItem(sub_comp.get("class_name", "")))
            self.table.setItem(row, 2, QTableWidgetItem(", ".join(sub_comp.get("nodes", []))))
            self.table.setCellWidget(row, 3, QPushButton("Edit"))  # Params 编辑按钮
            self.table.cellWidget(row, 3).clicked.connect(lambda checked, r=row: self.edit_params(r))
            self.set_params_to_row(row, sub_comp.get("Params",[]))
            self.table.setCellWidget(row, 4, QPushButton("Edit"))  # Sub Comps 编辑按钮
            self.table.cellWidget(row, 4).clicked.connect(lambda checked, r=row: self.edit_sub_comps(r))
            self.set_sub_comps_to_row(row, sub_comp.get("sub_comps",[]))

        self.layout.addWidget(self.table)

        # 添加按钮
        button_layout = QHBoxLayout()
        self.add_button = QPushButton("Add Sub Comp")
        self.add_button.clicked.connect(self.add_sub_comp)
        self.delete_button = QPushButton("Delete Sub Comp")
        self.delete_button.clicked.connect(self.delete_sub_comp)
        self.save_button = QPushButton("Save")
        self.save_button.clicked.connect(self.accept)
        button_layout.addWidget(self.add_button)
        button_layout.addWidget(self.delete_button)
        button_layout.addWidget(self.save_button)
        self.layout.addLayout(button_layout)

        self.setLayout(self.layout)

    def add_sub_comp(self):
        row_count = self.table.rowCount()
        self.table.insertRow(row_count)
        self.table.setItem(row_count, 0, QTableWidgetItem(""))
        self.table.setItem(row_count, 1, QTableWidgetItem(""))
        self.table.setItem(row_count, 2, QTableWidgetItem(""))
        self.table.setCellWidget(row_count, 3, QPushButton("Edit"))  # Params 编辑按钮
        self.table.cellWidget(row_count, 3).clicked.connect(lambda checked, r=row_count: self.edit_params(r))
        self.table.setCellWidget(row_count, 4, QPushButton("Edit"))  # Sub Comps 编辑按钮
        self.table.cellWidget(row_count, 4).clicked.connect(lambda checked, r=row_count: self.edit_sub_comps(r))

    def edit_params(self, row):
        current_params = self.get_params_from_row(row)
        dialog = ParamEditorDialog(self, current_params)
        if dialog.exec_() == QDialog.Accepted:
            new_params = dialog.get_params()
            self.set_params_to_row(row, new_params)

    def get_params_from_row(self, row):
        item = self.table.item(row, 3)
        if item:
            return json.loads(item.text()) if item.text() else []
        return []

    def set_params_to_row(self, row, params):
        self.table.setItem(row, 3, QTableWidgetItem(json.dumps(params)))

    def edit_sub_comps(self, row):
        current_sub_comps = self.get_sub_comps_from_row(row)
        dialog = SubCompEditorDialog(self, current_sub_comps)
        if dialog.exec_() == QDialog.Accepted:
            new_sub_comps = dialog.get_sub_comps()
            self.set_sub_comps_to_row(row, new_sub_comps)

    def get_sub_comps_from_row(self, row):
        item = self.table.item(row, 4)
        if item:
            return json.loads(item.text()) if item.text() else []
        return []

    def set_sub_comps_to_row(self, row, sub_comps):
        self.table.setItem(row, 4, QTableWidgetItem(json.dumps(sub_comps)))

    def get_sub_comps(self):
        sub_comps = []
        for row in range(self.table.rowCount()):
            sub_comp = {
                "name": self.table.item(row, 0).text() if self.table.item(row, 0) else "",
                "class_name": self.table.item(row, 1).text() if self.table.item(row, 1) else "",
                "nodes": self.table.item(row, 2).text().replace(" ","").split(",") if self.table.item(row, 2) else [],
                "Params": self.get_params_from_row(row),
                "sub_comps": self.get_sub_comps_from_row(row)
            }
            sub_comps.append(sub_comp)
        return sub_comps
    
    def delete_sub_comp(self):
        selected_rows = self.table.selectionModel().selectedRows()
        if selected_rows:
            for row in sorted(selected_rows, reverse=True):
                self.table.removeRow(row.row())
        else:
            QMessageBox.warning(self, "Warning", "No component selected to delete.")


class CompListTab(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.initUI()

    def initUI(self):
        self.layout = QVBoxLayout()

        # 表格显示元件列表
        self.table = QTableWidget()
        self.table.setRowCount(0)
        self.table.setColumnCount(5)
        self.table.setHorizontalHeaderLabels(["Name", "Class Name", "Nodes", "Params", "Sub Comps"])
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.layout.addWidget(self.table)

        # 添加和删除按钮
        button_layout = QHBoxLayout()
        self.add_button = QPushButton("Add Component")
        self.add_button.clicked.connect(self.add_component)
        self.delete_button = QPushButton("Delete Component")
        self.delete_button.clicked.connect(self.delete_component)
        button_layout.addWidget(self.add_button)
        button_layout.addWidget(self.delete_button)
        self.layout.addLayout(button_layout)

        self.setLayout(self.layout)

    def add_component(self):
        row_count = self.table.rowCount()
        self.table.insertRow(row_count)
        self.table.setItem(row_count, 0, QTableWidgetItem(""))  # Name
        self.table.setItem(row_count, 1, QTableWidgetItem(""))  # Class Name
        self.table.setItem(row_count, 2, QTableWidgetItem(""))  # Nodes
        self.table.setCellWidget(row_count, 3, QPushButton("Edit"))  # Params
        self.table.cellWidget(row_count, 3).clicked.connect(lambda checked, r=row_count: self.edit_params(r))
        self.table.setCellWidget(row_count, 4, QPushButton("Edit"))  # Sub Comps
        self.table.cellWidget(row_count, 4).clicked.connect(lambda checked, r=row_count: self.edit_sub_comps(r))

    def delete_component(self):
        selected_rows = self.table.selectionModel().selectedRows()
        if selected_rows:
            for row in sorted(selected_rows, reverse=True):
                self.table.removeRow(row.row())
        else:
            QMessageBox.warning(self, "Warning", "No component selected to delete.")

    def edit_params(self, row):
        current_params = self.get_component_params(row)
        dialog = ParamEditorDialog(self, current_params)
        if dialog.exec_() == QDialog.Accepted:
            new_params = dialog.get_params()
            self.set_component_params(row, new_params)

    def get_component_params(self, row):
        item = self.table.item(row, 3)
        if item:
            return json.loads(item.text()) if item.text() else []
        return []

    def set_component_params(self, row, params):
        self.table.setItem(row, 3, QTableWidgetItem(json.dumps(params)))

    def edit_sub_comps(self, row):
        current_sub_comps = self.get_component_sub_comps(row)
        dialog = SubCompEditorDialog(self, current_sub_comps)
        if dialog.exec_() == QDialog.Accepted:
            new_sub_comps = dialog.get_sub_comps()
            self.set_component_sub_comps(row, new_sub_comps)

    def get_component_sub_comps(self, row):
        item = self.table.item(row, 4)
        if item:
            return json.loads(item.text()) if item.text() else []
        return []

    def set_component_sub_comps(self, row, sub_comps):
        self.table.setItem(row, 4, QTableWidgetItem(json.dumps(sub_comps)))

    def get_components(self):
        components = []
        for row in range(self.table.rowCount()):
            component = {
                "name": self.table.item(row, 0).text() if self.table.item(row, 0) else "",
                "class_name": self.table.item(row, 1).text() if self.table.item(row, 1) else "",
                "nodes": self.table.item(row, 2).text().replace(" ", "").split(",") if self.table.item(row, 2) else [],
                "Params": self.get_component_params(row),
                "sub_comps": self.get_component_sub_comps(row)
            }
            components.append(component)
        return components

    def load_components(self, components):
        """递归加载组件及其子组件"""
        for component in components:
            self.add_component()
            row = self.table.rowCount() - 1
            self.table.setItem(row, 0, QTableWidgetItem(component.get("name", "")))
            self.table.setItem(row, 1, QTableWidgetItem(component.get("class_name", "")))
            self.table.setItem(row, 2, QTableWidgetItem(", ".join(component.get("nodes", []))))
            self.set_component_params(row, component.get("Params", []))
            self.set_component_sub_comps(row, component.get("sub_comps", []))

            # 递归加载子组件
            sub_comps = component.get("sub_comps", [])
            if sub_comps:
                self.load_components(sub_comps)